using DotPulsar;
using DotPulsar.Extensions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using tafei_thingsapi.Models;
using tafei_thingsapi.Models.Dtos;
using tafei_thingsapi.Services;
using Microsoft.Extensions.Logging;

namespace tafei_thingsapi.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class DevicesController : ControllerBase
    {
        private readonly tafei_thingsapiContext _context;
        private readonly OneNetService _oneNetService;
        private readonly HuaweiVideoService _huaweiVideoService;
        private readonly ILogger<DevicesController> _logger;

        public DevicesController(tafei_thingsapiContext context, OneNetService oneNetService, HuaweiVideoService huaweiVideoService, ILogger<DevicesController> logger)
        {
            _context = context;
            _oneNetService = oneNetService;
            _huaweiVideoService = huaweiVideoService;
            _logger = logger;
        }

        private bool IsAdmin()
        {
            // 这里应该实现从请求中获取用户角色并判断是否为管理员
            // 实际项目中应该使用认证中间件如JWT来获取用户信息
            var userId = int.Parse(User.FindFirst(ClaimTypes.NameIdentifier)?.Value);
            var user = _context.Users.Find(userId);
            return user?.Role == "admin";
        }

        // 获取所有设备
        [HttpGet]
        public async Task<ActionResult<IEnumerable<Device>>> GetDevices()
        {
            return await _context.Devices
                .Include(d => d.Owner)
                .ToListAsync();
        }

        // 获取用户的所有设备（包括拥有的和分享的）
        [HttpGet("user/{userId}")]
        public async Task<ActionResult<IEnumerable<Device>>> GetUserDevices(int userId)
        {
            // 获取用户拥有的设备
            var ownedDevices = await _context.Devices
                .Where(d => d.OwnerId == userId)
                .ToListAsync();

            // 获取分享给用户的设备
            var sharedDevices = await _context.DeviceShares
                .Where(ds => ds.SharedUserId == userId && ds.IsActive)
                .Include(ds => ds.Device)
                .Select(ds => ds.Device)
                .ToListAsync();

            // 合并结果
            var allDevices = ownedDevices.Concat(sharedDevices).ToList();
            foreach (var d in allDevices)
            {
                var deviceInfo = await _oneNetService.GetDeviceAsync(d.DeviceNumber);
                d.Status = deviceInfo?.data?.status == 1 ? "online" : deviceInfo?.data?.status == 0 ? "offline" : "unknown";
            }
            return allDevices;
        }


        [HttpGet("properties/{deviceId}")]
        public async Task<ActionResult<DeviceProperties>> GetDeviceProperties(int deviceId)
        {
            var device = await _context.Devices.FindAsync(deviceId);
            if (device == null)
            {
                return NotFound();
            }
            var properties = await _oneNetService.GetLatestDevicePropertiesAsync(device.DeviceNumber);
            _logger.LogInformation("获取设备属性详情: {DeviceId}, {Properties}", device.DeviceNumber, JsonSerializer.Serialize(properties));
            return new DeviceProperties
            {
                properties = properties?.data.ToDictionary(x => x.identifier, x => x),
                // videoUrl = await _huaweiVideoService.GetLiveUrlAsync(device.DeviceNumber)
            };
        }

        // 订阅设备消息流
        [HttpGet("stream/{deviceId}")]
        public async Task StreamDeviceMessages(int deviceId)
        {
            var device = _context.Devices.FirstOrDefault(d => d.Id == deviceId);
            if (device == null)
            {
                Response.StatusCode = 400;
                await Response.Body.WriteAsync(Encoding.UTF8.GetBytes("device not found in db"));
                _logger.LogError("device not found in db");
                return;
            }

            // // 确保消息队列存在
            // if (!_oneNetService.MsgQueue.ContainsKey(device.DeviceNumber))
            // {
            //     _oneNetService.MsgQueue.Add(device.DeviceNumber, new Queue<ThingPropertyMessage>(5));
            // }

            // 设置SSE响应头

            Response.Headers["Content-Type"] = "text/event-stream";
            Response.Headers["Cache-Control"] = "no-cache";
            // Response.Headers["Connection"] = "keep-alive";

            var streamWriter = new StreamWriter(Response.Body, Encoding.UTF8);
            var lastActivityTime = DateTime.UtcNow;
            ThingPropertyMessage lastmsg = null;
            try
            {
                while (!HttpContext.RequestAborted.IsCancellationRequested)
                {
                    if (_oneNetService.MsgQueue.ContainsKey(device.DeviceNumber))
                    {
                        var msg = _oneNetService.MsgQueue[device.DeviceNumber]; 
                        if (msg != null && msg != lastmsg)
                        {
                            // _logger.LogInformation("send msg: {Msg}", msg.ToString());
                            await streamWriter.WriteLineAsync($"data: {msg}");
                            await streamWriter.WriteLineAsync();
                            await streamWriter.FlushAsync();
                            lastActivityTime = DateTime.UtcNow;
                            lastmsg = msg;
                        }
                    }
                    if ((DateTime.UtcNow - lastActivityTime).TotalSeconds > 30)
                    {
                        // 发送心跳保持连接
                        await streamWriter.WriteLineAsync(":heartbeat\n");
                        await streamWriter.FlushAsync();
                        lastActivityTime = DateTime.UtcNow;
                    }
                    await Task.Delay(100); // 减少CPU使用率
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "SSE连接异常");
            }
            finally
            {
                streamWriter.Dispose();
                _logger.LogInformation("stream closed for device {DeviceId}", deviceId);
            }

        }

        // // 发送消息到指定设备的订阅者
        // public static async Task SendMessageToSubscribers(string deviceId, object message)
        // {
        //     if (_streams.TryGetValue(deviceId, out var stream))
        //     {
        //         try
        //         {
        //             var json = JsonSerializer.Serialize(message);
        //             await stream.WriteLineAsync($"data: {json}");
        //             await stream.WriteLineAsync();
        //             await stream.FlushAsync();
        //         }
        //         catch
        //         {
        //             _streams.Remove(deviceId);
        //             stream.Dispose();
        //         }
        //     }
        // }

        // 创建设备
        [HttpPost]
        public async Task<ActionResult<Device>> CreateDevice(Device device)
        {
            //获取当前用户ID
            var userId = int.Parse(User.FindFirst(ClaimTypes.NameIdentifier)?.Value);
            device.OwnerId = userId;
            _context.Devices.Add(device);

            var result = await _oneNetService.CreateDeviceAsync(new CreateDeviceRequest
            {
                device_name = device.DeviceNumber,
                desc = "自动创建"
            });
            // var huaweiResult = await _huaweiVideoService.BatchAddGBDevicesAsync(new BatchAddGBDevicesRequest
            // {
            //     devices = new BatchAddGBDevicesReqItem[]{
            //         new BatchAddGBDevicesReqItem{
            //             device_id = device.DeviceNumber,
            //             device_name = device.Name,
            //             device_username = "tafei",
            //             device_password = "Tafei@2025",
            //             description = "自动创建",
            //             algorithm = "MD5"
            //         }
            //     }
            // });
            await _context.SaveChangesAsync();

            return CreatedAtAction(nameof(GetDevices), new { id = device.Id }, device);
        }

        // 更新设备
        [HttpPut("{id}")]
        public async Task<IActionResult> UpdateDevice(int id, Device device)
        {
            if (id != device.Id)
            {
                return BadRequest();
            }

            _context.Entry(device).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!DeviceExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return NoContent();
        }

        // 删除设备
        [HttpDelete("{id}")]
        public async Task<IActionResult> DeleteDevice(int id)
        {
            var device = await _context.Devices.FindAsync(id);
            if (device == null)
            {
                return NotFound();
            }

            _context.Devices.Remove(device);
            await _context.SaveChangesAsync();

            return NoContent();
        }

        private bool DeviceExists(int id)
        {
            return _context.Devices.Any(e => e.Id == id);
        }


        private void PMonitor(ConsumerStateChanged stateChanged, CancellationToken cancellationToken)
        {
            var state = stateChanged.ConsumerState;
            var stateMessage = state switch
            {
                ConsumerState.Active => "The consumer is active",
                ConsumerState.Inactive => "The consumer is inactive",
                ConsumerState.Disconnected => "The consumer is disconnected",
                ConsumerState.Closed => "The consumer has closed",
                ConsumerState.ReachedEndOfTopic => "The consumer has reached end of topic",
                ConsumerState.Faulted => "The consumer has faulted",
                ConsumerState.Unsubscribed => "The consumer is unsubscribed.",
                _ => $"The consumer has an unknown state '{state}'"
            };
            var topic = stateChanged.Consumer.Topic;
            Console.WriteLine($"The consumer for topic '{topic}' " + stateMessage);
        }

        [HttpPost("{id}/command")]
        public async Task<IActionResult> ExecuteCommand(int id, [FromBody] CommandRequest request)
        {
            try
            {
                var device = await _context.Devices.FindAsync(id);
                if (device == null)
                {
                    return NotFound();
                }

                // 通过OneNET发送命令
                // var result = await _oneNetService.SendCommand(device.DeviceNumber, request.Command);
                var result = await _oneNetService.SetDevicePropertiesAsync(device.DeviceNumber, new Dictionary<string, object> { { request.key, request.value } });
                _logger.LogInformation("执行命令: {DeviceId}, {Command}", device.DeviceNumber, JsonSerializer.Serialize(request));
                if (result.code == 0)
                {
                    return Ok(new { success = true, message = "命令已发送" });
                }
                return BadRequest(result);
            }
            catch (Exception ex)
            {
                return StatusCode(500, new { success = false, message = ex.Message });
            }
        }



        public class CommandRequest
        {
            public string key { get; set; }
            public object value { get; set; }
        }

        public class FrequencyRequest
        {
            public int Frequency { get; set; }
        }
    }


}